// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#pragma once

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

#include <glog/logging.h>
#include <google/protobuf/message.h>
#include <google/protobuf/util/json_util.h>
#include <nlohmann/json.hpp>

namespace coin2::exchange::order {
class OrderConnectionConfig;
}

namespace coin2::exchange::base::market {
struct MarketExchangeApi;
}

namespace coin2::exchange::base::order {

class RateConfig {
 public:
  using MarketExchangeApi = coin2::exchange::base::market::MarketExchangeApi;

 public:
  static auto Get() -> std::unique_ptr<RateConfig>;
  static void CheckFail(std::string_view mea_str, std::string_view example);
  static auto GetMeStringFromMea(const MarketExchangeApi& mea) -> std::string;
  static bool LoadConfigFromJson(const nlohmann::json& json, google::protobuf::Message* config);
  static void MergeFromConfig(
      const std::string field_name,
      const google::protobuf::Message& src_cfg,
      google::protobuf::Message* dst_cfg);

 public:
  RateConfig(const RateConfig&) = delete;
  RateConfig& operator=(const RateConfig&) = delete;
  ~RateConfig() = default;

  void LoadDefaultConfig(const std::string& mea_str, google::protobuf::Message* config) const;
  void GetConfig(
      const MarketExchangeApi& mea,
      const coin2::exchange::order::OrderConnectionConfig& cfg,
      google::protobuf::Message* config) const;

  std::string DebugString() const { return config_.dump(); }

 protected:
  explicit RateConfig(std::string_view cfg_file);

 private:
  static const std::string cfg_path_;

 private:
  nlohmann::json config_;
};

}  // namespace coin2::exchange::base::order
